package com.library.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.library.entity.BorrowRecord;
import com.library.entity.Book;
import com.library.mapper.BorrowRecordMapper;
import com.library.service.BorrowRecordService;
import com.library.service.BookService;
import com.library.vo.PageVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 借阅记录Service实现
 *
 * @author Library Team
 */
@Slf4j
@Service
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements BorrowRecordService {

    @Autowired
    private BookService bookService;

    @Override
    public PageVO<BorrowRecord> getBorrowRecordPage(Long current, Long size, Long userId) {
        Page<BorrowRecord> page = new Page<>(current, size);
        IPage<BorrowRecord> result = baseMapper.selectBorrowRecordPage(page, userId);

        // 手动填充关联字段
        List<BorrowRecord> records = result.getRecords();
        for (BorrowRecord record : records) {
            record.setUsername(record.getUsername());
            record.setBookTitle(record.getBookTitle());
            record.setBookAuthor(record.getBookAuthor());
        }

        PageVO<BorrowRecord> vo = new PageVO<>();
        vo.setCurrent(result.getCurrent());
        vo.setSize(result.getSize());
        vo.setTotal(result.getTotal());
        vo.setPages(result.getPages());
        vo.setRecords(records);

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean borrowBook(Long userId, Long bookId, Integer borrowDays) {
        // 检查书籍是否存在且可借
        Book book = bookService.getBookById(bookId);
        if (book == null) {
            throw new RuntimeException("书籍不存在");
        }

        if (book.getAvailableQuantity() <= 0) {
            throw new RuntimeException("书籍已借完");
        }

        // 检查用户是否已借阅此书
        if (isBookBorrowedByUser(userId, bookId)) {
            throw new RuntimeException("您已借阅此书");
        }

        // 检查用户当前借阅数量（限制最多5本）
        int currentBorrowCount = getCurrentBorrowCount(userId);
        if (currentBorrowCount >= 5) {
            throw new RuntimeException("您当前借阅书籍数量已达上限（5本）");
        }

        // 创建借阅记录
        BorrowRecord record = new BorrowRecord();
        record.setUserId(userId);
        record.setBookId(bookId);
        record.setBorrowDate(LocalDateTime.now());
        record.setDueDate(LocalDateTime.now().plusDays(borrowDays != null ? borrowDays : 30));
        record.setStatus("BORROWED");

        boolean result = save(record);

        if (result) {
            // 更新书籍可借数量
            bookService.updateAvailableQuantity(bookId, -1);
            log.info("用户 {} 借阅书籍 {} 成功", userId, bookId);
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean returnBook(Long recordId) {
        // 查询借阅记录
        BorrowRecord record = getById(recordId);
        if (record == null) {
            throw new RuntimeException("借阅记录不存在");
        }

        if (!"BORROWED".equals(record.getStatus())) {
            throw new RuntimeException("此书籍已归还");
        }

        // 更新记录状态
        record.setReturnDate(LocalDateTime.now());
        record.setStatus("RETURNED");
        record.setUpdatedAt(LocalDateTime.now()); // 设置更新时间，避免数据库约束违反

        boolean result = updateById(record);

        if (result) {
            // 更新书籍可借数量
            bookService.updateAvailableQuantity(record.getBookId(), 1);
            log.info("归还书籍成功 - 记录ID: {}", recordId);
        }

        return result;
    }

    @Override
    public boolean isBookBorrowedByUser(Long userId, Long bookId) {
        LambdaQueryWrapper<BorrowRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BorrowRecord::getUserId, userId)
               .eq(BorrowRecord::getBookId, bookId)
               .eq(BorrowRecord::getStatus, "BORROWED");
        return count(wrapper) > 0;
    }

    @Override
    public int getCurrentBorrowCount(Long userId) {
        return baseMapper.countBorrowedByUserId(userId, "BORROWED");
    }

}
